package com.lw.smartquiz.assess;

import com.lw.smartquiz.common.ErrorCode;
import com.lw.smartquiz.exception.BusinessException;
import com.lw.smartquiz.exception.ThrowUtils;
import com.lw.smartquiz.model.entity.App;
import com.lw.smartquiz.model.entity.UserAnswer;
import com.lw.smartquiz.model.enums.AppTypeEnum;
import com.lw.smartquiz.model.enums.ScoringStrategyEnum;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 评判策略环境类
 * 使用注解标记应用类型和评分策略，同时用Spring容器管理策略类，就可以遍历策略类来匹配参数，选择相应的策略类
 */
@Service
public class AssessStrategyExecutor {
    @Resource
    private List<AssessStrategy> assessStrategyList;

    public UserAnswer doScore(List<String> choices, App app) {
        //获取应用类型和评分策略
        AppTypeEnum appTypeEnum = AppTypeEnum.getEnumByValue(app.getAppType());
        ScoringStrategyEnum scoringStrategyEnum = ScoringStrategyEnum.getEnumByValue(app.getScoringStrategy());
        //若不存在，则抛异常
        ThrowUtils.throwIf(appTypeEnum == null || scoringStrategyEnum == null, ErrorCode.OPERATION_ERROR, "应用类型或计分策略错误");

        //遍历所有策略类，找到对应的策略来调用
        for (AssessStrategy assessStrategy : assessStrategyList) {
            if (assessStrategy.getClass().isAnnotationPresent(AssessStrategyConfig.class)) {
                AssessStrategyConfig assessStrategyConfig = assessStrategy.getClass().getAnnotation(AssessStrategyConfig.class);
                if (appTypeEnum.equals(assessStrategyConfig.appType()) && scoringStrategyEnum.equals(assessStrategyConfig.strategyType())){
                    return assessStrategy.doScore(choices, app);
                }
            }
        }
        //若没有找到对应的策略，则抛异常
        throw new BusinessException(ErrorCode.SYSTEM_ERROR, "没有找到对应的计分策略");
    }
}
